home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ivl
/
src
/
hufilec.ars
< prev
next >
Wrap
Text File
|
2000-06-17
|
44KB
|
1,663 lines
/*
* ファイル取り扱い関数群(for Human68k)
*
* from Dec. 3,1993 by dummy.x.(with J-S.I.)
*
* このソースは arr.x によってコンパイルされます。
*/
-* -O -Wall
-
- ここからしばらくアセンブラソース
-
-- Common Header
.include doscall.mac
.include iocscall.mac
.nlist
.include general.mac
.list
-_isponly.s
* 定数定義
* __FILES バッファ構造
.offset 0
__ATR: .ds.b 1
__DRVNO: .ds.b 1
__DIRCLS: .ds.w 1
__DIRFAT: .ds.w 1
__DIRSEC: .ds.w 1
__DIRPOS: .ds.w 1
__FILENAME: .ds.b 8
__EXT: .ds.b 3
_ATR: .ds.b 1
_TIME: .ds.w 1
_DATE: .ds.w 1
_FILELEN: .ds.l 1
_NAME: .ds.b 18+1+3+1 *<base>+'.'+<ext>+'\0'
.even.
_FBUF_LEN:
* スタックフレーム状況
LOCALSIZE equ -(_FBUF_LEN)
.offset LOCALSIZE
_FBUF: .ds.b _FBUF_LEN *__FILES バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
.text
.even
*---------------------------------------------------------------
*int is_path_only(const char *fnamp)
* 指定されたファイル名が、実はパス名だけかどうか調べる
* 引数: fnamp - 被検査ファイル名へのポインタ
* 返値: パス名だけだったら !0、ファイル名も含まれていたら 0
* 注記 * おそらく、判断条件は今のままでは不完全である。
*---------------------------------------------------------------
.xdef _is_path_only
_is_path_only:
link a6,#LOCALSIZE
move.l _FNAMP(a6),d1 *d1.l=fnamp
* 文字列の最後がパス区切り文字ならパス名
move.l d1,a0 *a0=fnamp
@@: tst.b (a0)+
bne.s @b
move.b -2(a0),d0 *d0.b=最後の一文字
cmp.b #'\',d0
beq.s ispo_only
cmp.b #':',d0
beq.s ispo_only
cmp.b #'/',d0
beq.s ispo_only
* 同名のディレクトリが既に存在していて、
move.w #SUBDIR,-(sp)
move.l d1,-(sp)
pea.l _FBUF(a6)
DOS __FILES
tst.l d0
bmi.s ispo_not
* しかもワイルドカードが使われていなければパス名
cmp.w #$ffff,_FBUF+__DIRPOS(a6)
bne.s ispo_not
ispo_only: * パス名のみだッ!
moveq.l #1,d0
unlk a6
rts
ispo_not: * ファイル名も含まれているッ!
moveq.l #0,d0
unlk a6
rts
*---------------------------------------------------------------
.end
-_getxpos.s
* スタックフレーム状況
.offset 0
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
.text
.even
*---------------------------------------------------------------
*char *getextpos(const char *fnamp)
* 拡張子の存在位置を取得する
* 引数: fnamp - 被検査ファイル名アドレス
* 返値: 拡張子(らしきもの)があればその開始位置('.'の位置)
* なければ NULL
*---------------------------------------------------------------
.xdef _getextpos
_getextpos:
move.l _FNAMP(sp),d2
moveq.l #0,d0 *d0.l=拡張子がなかった時の返値(NULL)
move.l d2,a0
@@: tst.b (a0)+ *fnamp の最後へ移動する
bne.s @b *
subq.w #1,a0 *行き過ぎたぶん引き戻す
bra.s gxpos_loop * ※getextpos0() 内のラベルに飛ぶ
*---------------------------------------------------------------
*char *getextpos0(const char *fnamp)
* 拡張子の存在位置を取得する(ない時は最後の '\0' アドレスを返す版)
* 引数: fnamp - 被検査ファイル名アドレス
* 返値: 拡張子(らしきもの)があればその開始位置('.'の位置)
* なければ fnamp の最後の '\0' のアドレス
* 注記 * この関数で拡張子がなかったことを判断するには、
* 「返したアドレスの文字が '\0' か」
* を調べればいい。
*---------------------------------------------------------------
.xdef _getextpos0
_getextpos0:
move.l _FNAMP(sp),d2
move.l d2,a0
@@: tst.b (a0)+ *fnamp の最後へ移動する
bne.s @b *
subq.w #1,a0 *行き過ぎたぶん引き戻す
move.l a0,d0 *d0.l=拡張子がなかった時の返値('\0' の位置)
*※ここから下は getextpos() と共用している。
* 変更は“どちらにも影響がないように”気を付けて
*行なうように。
*
*ここに来た時点でのレジスタの意味:
* d0.l - 拡張子が見つからなかった時の返値
* d2.l - fnamp
* a0 - fnamp の最後 '\0' のアドレス
gxpos_loop:
cmp.l a0,d2 *ファイル名の先頭に
bhs.s gxpos0 *達したら拡張子は指定されていない
* 文字判定
move.b -(a0),d1 *d1.b=文字
* パス区切り文字判定
cmpi.b #'\',d1 *パス区切り文字に
beq.s gxpos0 *ぶつかっちゃったら
cmpi.b #':',d1 *拡張子は
beq.s gxpos0 *指定されていない
cmp.b #'/',d1 *
beq.s gxpos0 *
* 拡張子開始文字判定
cmp.b #'.',d1 *'.'だったら
bne.s gxpos_loop *拡張子発見!
gxpos_findext: * 拡張子発見
move.l a0,d0 *そのアドレスを返値に
gxpos0: * 共通脱出口
rts
*---------------------------------------------------------------
.end
-_fcatext.s
* スタックフレーム状況
;;;REGLST reg
.offset 0
;;; .ds.l 0 *退避レジスタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
_EXTP: .ds.l 1 *引数: extp
.text
.even
*---------------------------------------------------------------
*char *fcatext(char *fnamp, const char *extp)
* ファイル名に拡張子を付加する
* 拡張子がある場合は付加しない
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
* 注記 * extp の最初には '.'(ピリオド)があってもなくても構わない。
* * 付加する場合、fnamp の後ろには十分な余裕が必要である。
*---------------------------------------------------------------
.xdef _fcatext
_fcatext:
move.l _FNAMP(sp),d0
move.l _EXTP(sp),a1
move.l d0,a0
@@: tst.b (a0)+ *ファイル名末尾アドレスを取得
bne.s @b *
subq.w #1,a0 *行き過ぎたぶんを引き戻し
movea.l a0,a2 *そのアドレスを a2 にも持っておく
catx_findx: * 拡張子位置の取得
cmp.l a0,d0 *ファイル名の最初に達したら
bhs.s catx_cat *拡張子は指定されていない
* 文字判定
move.b -(a0),d1 *d1.b=文字
* パス区切り文字判定
cmpi.b #'\',d1 *パス区切り文字に
beq.s catx_cat *ぶつかっちゃったら
cmpi.b #':',d1 *拡張子は
beq.s catx_cat *指定されていない
cmp.b #'/',d1 *
beq.s catx_cat *
* 拡張子開始文字判定
cmp.b #'.',d1 *'.'でなければ
bne.s catx_findx *次の文字を調べる
catx0:
rts
catx_cat: * 拡張子を付加する
moveq.l #'.',d1
cmp.b (a1),d1 *extp に '.' がなかったら
beq.s @f *
move.b d1,(a2)+ *先に '.' を転送しておく
@@: * 拡張子を複写
move.b (a1)+,(a2)+
bne.s @b
rts
*---------------------------------------------------------------
.end
-_fchgext.s
* スタックフレーム状況
;;;REGLST reg
.offset 0
;;; .ds.l 0 *退避レジスタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
_EXTP: .ds.l 1 *引数: extp
.text
.even
*---------------------------------------------------------------
*char *fchgext(char *fnamp, const char *extp)
* ファイル名の拡張子を付け替える
* 拡張子がなければ付加する
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
* 注記 * extp の最初には '.'(ピリオド)があってもなくても構わない。
* * 付加する場合、fnamp の後ろには十分な余裕が必要である。
*---------------------------------------------------------------
.xdef _fchgext
_fchgext:
move.l _FNAMP(sp),d0
move.l _EXTP(sp),a1
move.l d0,a0
@@: tst.b (a0)+ *ファイル名末尾アドレスを取得
bne.s @b *
subq.w #1,a0 *行き過ぎたぶんを引き戻し
movea.l a0,a2 *そのアドレスを a2 にも持っておく
chgx_findx: * 拡張子位置の取得
cmp.l a0,d0 *ファイル名の最初に達したら
bhs.s chgx_nofound *拡張子は指定されていない
* 文字判定
move.b -(a0),d1 *d1.b=文字
* 拡張子開始文字判定
cmp.b #'.',d1 *'.'だったら
beq.s chgx_found *拡張子発見!
* パス区切り文字判定
cmpi.b #'\',d1 *パス区切り文字に
beq.s chgx_nofound *ぶつかっちゃったら
cmpi.b #':',d1 *拡張子は
beq.s chgx_nofound *指定されていない
cmp.b #'/',d1 *
bne.s chgx_findx *
chgx_nofound: * 拡張子がなかった
movea.l a2,a0 *ファイル名の後に付加する
chgx_found: *拡張子があった
chgx_chg: *拡張子付替
moveq.l #'.',d1
cmp.b (a1),d1 *extp に '.' がなかったら
beq.s @f *
move.b d1,(a0)+ *先に '.' を転送しておく
@@: * 拡張子を複写
move.b (a1)+,(a0)+
bne.s @b
chgx0:
rts
*---------------------------------------------------------------
.end
-_issamef.s
* 外部参照
.xref _memcmp,_stricmp * define in C libraly
.xref _strnicmp * define in dummyc.a
* 定数定義
* __FILES バッファ構造
.offset 0
__ATR: .ds.b 1
__DRVNO: .ds.b 1
__DIRCLS: .ds.w 1
__DIRFAT: .ds.w 1
__DIRSEC: .ds.w 1
__DIRPOS: .ds.w 1
__FILENAME: .ds.b 8
__EXT: .ds.b 3
_ATR: .ds.b 1
_TIME: .ds.w 1
_DATE: .ds.w 1
_FILELEN: .ds.l 1
_NAME: .ds.b 18+1+3+1 *<base>+'.'+<ext>+'\0'
.even.
_FBUF_LEN:
CMPSIZE_1 = __FILENAME *__ATR~__DIRPOS
CMPSIZE_2 = __EXT-__FILENAME *__FILENAME
CMPSIZE_3 = _ATR-__EXT *__EXT
CMPSIZE_4 = _NAME-_ATR *_ATR~_FILELEN
*CMPSIZE_5 は _NAME を文字列終わりまで比較
* スタックフレーム状況
REGLST reg d3/a3/a4/a5
LOCALSIZE equ -(_FBUF_LEN*2)
.offset LOCALSIZE
_FBUF1: .ds.b _FBUF_LEN *fn1p 用 __FILES バッファ
_FBUF2: .ds.b _FBUF_LEN *fn2p 用 __FILES バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_FN1P: .ds.l 1 *引数: fn1p
_FN2P: .ds.l 1 *引数: fn2p
.text
.even
*---------------------------------------------------------------
*int is_same_file(const char *fn1p, const char *fn2p)
* 二つのファイル名の指すファイルの実体が同じものかどうか調べる
* 引数: fn1p,fn2p - 被比較ファイル名1,2
* 返値: 二つが同じファイルなら !0、違っていたら 0
* 注記 * 片方のファイルが見つからない場合は、「違っている」として
* 0 を返す。
* また、両方とも見つからない場合は「同じ」として !0 を返す。
* 警告 * 現在の比較方法は、
* 「両方のファイルを _dos_files() にかけ、互いの
* _filbuf を公開/非公開部分を含めて全て比較する」
* というもので、決して完璧なものではない。
* また、lndrv や TwentyOne などの Human 拡張プログラムを
* 使われた場合の動作は不明である(少なくとも、「ファイル名の
* 大文字小文字を区別する」ようにした場合には確実に問題になる
* だろう)。
*---------------------------------------------------------------
.xdef _is_same_file
_is_same_file:
link a6,#LOCALSIZE
movem.l REGLST,-(sp)
moveq.l #0,d3 *d3=result
* fn1p を __FILES
lea.l _FBUF1(a6),a3 *a3=fbuf1
move.w #ARCHIVE,-(sp)
move.l _FN1P(a6),-(sp)
pea.l (a3)
DOS __FILES
lea.l 10(sp),sp
tst.l d0
smi.b d1 *d1.b=err1
* fn2p を __FILES
lea.l _FBUF2(a6),a4 *a4=fbuf2
move.w #ARCHIVE,-(sp)
move.l _FN2P(a6),-(sp)
pea.l (a4)
DOS __FILES
lea.l 10(sp),sp
tst.l d0
smi.b d0 *d0.b=err2
* __FILES の結果を見る
cmp.b d1,d0 *どちらも結果が
bne.s issamf0 *同じ値になってたら
* err1 によって状況判定
tst.b d1 *err1 != 0 なら
bne.s issamf_same *どっちもなかった...同じということにする
*どっちもあった...
* __FILES バッファの中身を比較
lea.l _memcmp(OPC),a5
pea.l CMPSIZE_1.w * __ATR~__DIRPOS
pea.l (a3)
pea.l (a4)
jsr (a5)
lea.l 12(sp),sp
tst.l d0
bne.s issamf0
pea.l CMPSIZE_4.w * _ATR~_FILELEN
pea.l _ATR(a3)
pea.l _ATR(a4)
jbsr (a5)
lea.l 12(sp),sp
tst.l d0
bne.s issamf0
lea.l _strnicmp(OPC),a5
pea.l CMPSIZE_2.w * __FILENAME
pea.l __FILENAME(a3)
pea.l __FILENAME(a4)
jbsr (a5)
lea.l 12(sp),sp
tst.l d0
bne.s issamf0
pea.l CMPSIZE_3.w * __EXT
pea.l __EXT(a3)
pea.l __EXT(a4)
jbsr (a5)
lea.l 12(sp),sp
tst.l d0
bne.s issamf0
pea.l _NAME(a3) * _NAME
pea.l _NAME(a4)
jbsr _stricmp
addq.w #8,sp
tst.l d0
bne.s issamf0
issamf_same: * 同じファイルだッ!
moveq.l #1,d3
issamf0:
move.l d3,d0
movem.l (sp)+,REGLST
unlk a6
rts
*---------------------------------------------------------------
.end
-_cfpaseq.s
* 外部参照
.xref _path_separator * define in dummyc.a
* スタックフレーム状況
REGLST reg a3-a5
.offset 0
.ds.l 3 *退避レジスタ
.ds.l 1 *リターンアドレス
_DSTP: .ds.l 1 *引数: dstp
_ENVPP: .ds.l 1 *引数: envpp
.text
.even
*---------------------------------------------------------------
*char *cut_from_pathseq(char *dstp, const char **envpp)
* 複数のパス名が並んでいる文字列の、最初のパス名を取り出す
* 同じパラメータで複数回呼び出すことで、並んでいる順に次のパス名を
* 取り出せる
*
* 引数: dstp - 複写先バッファアドレス
* envpp - パス名列へのポインタへのポインタ
* 返値: 通常は dstp の値、パス名列が終了していたら NULL
* (*dstp) - 取り出したパス名(定義終了時には空文字列)
* (*envpp) - 次のディレクトリ名の開始アドレス
* 注記 * 「パス名列が終了していた」となるのは、最後のパス名を
* 取り出した後に、更に取り出そうとした時である。
* * パス名は、環境変数 path の形式で並んでいるものとする。:
* <path1>;<path2>;..;<pathn>
*---------------------------------------------------------------
.xdef _cut_from_pathseq
_cut_from_pathseq:
movem.l REGLST,-(sp)
move.l _DSTP(sp),a3 *a3=dstp
move.l _ENVPP(sp),a4 *a4=envpp
movea.l (a4),a5 *a5=*envp
tst.b (a5) * パス名列が終了してたら
beq.s cpseq_ended * その処理を
cpseq_cont: * まだパス名がある
* パス名を '\0' か ';' まで切り出す
@@: move.b (a5)+,d0
beq.s cpseq_ct1
cmpi.b #';',d0
beq.s cpseq_ct1
move.b d0,(a3)+
bra.s @b
cpseq_ct1: * 「パス区切り文字」で終わっていなければ付加する
move.b -1(a3),d0 *d0.b=最後の文字
cmpi.b #'\',d0 *がパス区切り文字
beq.s cpseq_ct2 *
cmpi.b #':',d0 *
beq.s cpseq_ct2 *
cmpi.b #'/',d0 *
beq.s cpseq_ct2 *でなければ
jbsr _path_separator *パス区切り文字を
move.b d0,(a3)+ *書き加えて
cpseq_ct2:
clr.b (a3) *取り出したパス名を完結させる
* パス名列が ';' で終わってたら飛ばしておく
tst.b -1(a5) *ループの都合で1文字進んでいる
bne.s @f *終わったのが '\0' だったなら
subq.w #1,a5 *1文字戻す('\0' を指すように)
@@: move.l a5,(a4) *そのアドレスをバッファに収める
*返値を設定
move.l _DSTP(sp),d0 *dstp を返す
cpseq0:
movem.l (sp)+,REGLST
rts
cpseq_ended: * パス名列は終了している
clr.b (a3) *バッファは空文字列
moveq.l #0,d0 *NULL を返す
bra.s cpseq0
*---------------------------------------------------------------
.end
-_apatsep.s
* 外部参照
.xref _path_separator * define in dummyc.a
* スタックフレーム状況
REGLST reg d3/a3
.offset 0
.ds.l 1+1 *退避レジスタ
.ds.l 1 *リターンアドレス
_DIRNAMP: .ds.l 1 *引数: dirnamp
.text
.even
*---------------------------------------------------------------
*char *append_path_separator(char *dirnamp)
* ディレクトリ名末尾にパス区切り文字がなければ付加する
* 引数: dirnamp - 被処理ディレクトリ名
* 返値: dirnamp の値
* 注記 * dirnamp には、最低 2.b の余白が必要である。
*---------------------------------------------------------------
.xdef _append_path_separator
_append_path_separator:
movem.l REGLST,-(sp)
move.l _DIRNAMP(sp),d3 *d3.l=dirnamp
move.l d3,a3 *a3=dirnamp
@@: tst.b (a3)+ *文字列の最後まで
bne.s @b *進めてから
subq.l #2,a3 *最後の文字まで戻る
move.b (a3)+,d0 *d0.b=最後の文字
cmp.b #'\',d0 *がパス区切り文字
beq.s apps0 *
cmp.b #':',d0 *
beq.s apps0 *
cmp.b #'/',d0 *
beq.s apps0 *でなかったら
jbsr _path_separator *パス区切り文字を
move.b d0,(a3)+ *書き加えて
clr.b (a3) *文字列を完結させる
apps0:
move.l d3,d0 *dirnamp を返す
movem.l (sp)+,REGLST
rts
*---------------------------------------------------------------
.end
-_gevpath.s
* 外部参照
.xref _getenv * define in C library.
.xref _path_separator * define in dummyc.a
* スタックフレーム状況
REGLST reg a3
.offset 0
.ds.l 1 *退避レジスタ
.ds.l 1 *リターンアドレス
_BUFP: .ds.l 1 *引数: bufp
_ENVNAMP: .ds.l 1 *引数: envnamp
.text
.even
*---------------------------------------------------------------
*char *get_env_path(char *bufp, const char *envnamp)
* 環境変数に定義されたパス名の取得
* 引数: bufp - 取得パス名格納バッファアドレス
* envnamp - 環境変数名文字列アドレス
* 返値: bufp の値
* 注記 * 取得したパス名の最後に '\' か ':' か '/' がない場合、
* 環境変数 SLASH が定義されていれば '/'
* されていなければ '\'
* を書き加える。
* * 指定の環境変数が定義されていなかったら bufp は
* 一切書き換えない。
*---------------------------------------------------------------
.xdef _get_env_path
_get_env_path:
move.l REGLST,-(sp)
move.l _BUFP(sp),a3
* 環境変数取得
move.l _ENVNAMP(sp),-(sp)
jbsr _getenv
addq.w #4,sp
move.l d0,a0 * 環境変数が定義されてなければ
beq.s gevpat0 * 何もしないで返る
* 定義内容をバッファに複写
@@: move.b (a0)+,(a3)+
bne.s @b * a0,a3 は共に1文字ぶん行きすぎてるので注意
* 「パス区切り文字」で終わっていなければ付加する
subq.l #2,a3 *最後の文字まで引き戻す
move.b (a3)+,d0 *d0.b=最後の文字
cmpi.b #'\',d0 *がパス区切り文字
beq.s gevpat0 *
cmpi.b #':',d0 *
beq.s gevpat0 *
cmpi.b #'/',d0 *
beq.s gevpat0 *でなかったら
jbsr _path_separator *パス区切り文字を
move.b d0,(a3)+ *末尾追加して
clr.b (a3) *文字列を完結
gevpat0: * 共通脱出口
move.l _BUFP(sp),d0 *bufp を返す
move.l (sp)+,REGLST
rts
*---------------------------------------------------------------
.end
-_pathsep.s
* 外部参照
.xref _getenv * define in C library.
.xref __path_separator_envname *define in dummyc.a
.text
.even
*---------------------------------------------------------------
*char path_separator(void)
* ディレクトリの区切り文字を取得する
* 返値: 環境変数 SLASH が定義されていれば '/'
* されていなければ '\'
*---------------------------------------------------------------
REGLST reg d3/a3
.xdef _path_separator
_path_separator:
movem.l REGLST,-(sp)
moveq.l #0,d3
lea.l _?sep_0(OPC),a3 *a3=取得済み文字格納バッファ
move.b (a3),d3 *既に取得済みなら
bne.s patsep0 *余計な処理をせずに済ませる
* 環境変数が定義されているかどうかで文字を決める
pea.l __path_separator_envname(OPC) *環境変数名
jbsr _getenv
addq.w #4,sp
tst.l d0 *環境変数が定義されてるかで
bne.s patsep_define *文字を変える
patsep_undef: * 定義されていない
move.b #'\',d3
bra.s patsep_stock
patsep_define: * 定義されている
move.b #'/',d3
patsep_stock:
move.b d3,(a3)
patsep0:
move.l d3,d0
movem.l (sp)+,REGLST
rts
*---------------------------------------------------------------
.bss
_?sep_0: ;取得済みパス区切り文字
.ds.b 1
*---------------------------------------------------------------
.end
-_isthpath.s
.text
* 外部参照
.xref _strpbrk * define in C library.
* スタックフレーム状況
.offset 0
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
.text
.even
*---------------------------------------------------------------
*int is_there_path(const char *fnamp)
* ファイル名にパス名が指定されているか調べる
* 引数: fnamp - 被検査ファイル名へのポインタ
* 返値: パス名が指定されていれば !0、されていなければ 0
* 注記 * パス名が指定されているかは、「ファイル名に
* '\' か '/' か ':' があるかどうか」で調べている。
*---------------------------------------------------------------
.xdef _is_there_path
_is_there_path:
move.l _FNAMP(sp),d0
pea.l ?C0(OPC)
move.l d0,-(sp)
jbsr _strpbrk
addq.w #8,sp
tst.l d0
sne.b d1
moveq.l #1,d0
move.b d1,d0 *d0.l=ff(!0):パス名指定あり/=0:指定なし
rts
*---------------------------------------------------------------
.text
?C0: * パス区切り文字群
.dc.b '\/:',0
*---------------------------------------------------------------
.end
-_getfsiz.s
* 定数定義
_FLS_FILELEN equ 26 *__FILES バッファ:ファイルサイズ
* スタックフレーム状況
LOCALSIZE equ -54
.offset LOCALSIZE
_FILESBUF: .ds.b 54 *__FILES バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
.text
.even
*---------------------------------------------------------------
*long get_file_size(const char *fnamp)
* 指定ファイルのファイルサイズを取得する
* 引数: fnamp - ファイル名文字列へのポインタ
* 返値: ファイルサイズ(>=0)、ファイルがなかったら <0
* 注記 * ファイルがとんでもなく大きい(2Gを超えるような)場合、
* エラーとして扱われてしまう(負値になってしまうため)。
*---------------------------------------------------------------
.xdef _get_file_size
_get_file_size:
link a6,#LOCALSIZE
move.w #$2f,-(sp)
move.l _FNAMP(a6),-(sp)
pea.l _FILESBUF(a6)
DOS __FILES
tst.l d0
bmi.s gfsz0
move.l _FILESBUF+_FLS_FILELEN(a6),d0
gfsz0:
unlk a6
rts
*---------------------------------------------------------------
.end
-_ispasep.s
* スタックフレーム状況
.offset 0
.ds.l 1 *リターンアドレス
_CH: .ds.l 1 *引数: ch
.text
.even
*---------------------------------------------------------------
*int is_path_separator(int ch)
* 文字がパス名の区切り文字かを調べる
* 引数: ch - 被検査文字
* 返値: 区切り文字('\', '/', ':')なら !0、違うならば 0
* 注記 * これで言う「区切り文字」とは '\'(バックスラッシュ),
* '/'(スラッシュ), ':'(セミコロン) のどれかである。
*---------------------------------------------------------------
.xdef _is_path_separator
_is_path_separator:
move.b _CH+3(sp),d1
moveq.l #0,d0
cmpi.b #'\',d1
beq.s ips_not
cmpi.b #':',d1
beq.s ips_not
cmpi.b #'/',d1
bne.s ips0
ips_not:
moveq.l #1,d0
ips0:
rts
*---------------------------------------------------------------
.end
-_gdrvfre.s
* スタックフレーム状況
LOCALSIZE equ -8
.offset LOCALSIZE
_FREBUF: .ds.b 8 *__DSKFRE バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_DRVNO: .ds.l 1 *引数: drvno
.text
.even
*---------------------------------------------------------------
*long get_drive_free(int drvno)
* 指定ドライブ番号の空き容量を得る
* 引数: drvno - ドライブ番号(=0:カレント/=1-26:A-Z)
* 返値: 空き容量(byte単位)
* 値が負数の場合はエラー
*---------------------------------------------------------------
.xdef _get_drive_free
_get_drive_free:
link a6,#LOCALSIZE
pea _FREBUF(a6)
move.w 10(a6),-(sp)
DOS __DSKFRE
unlk a6
rts
*---------------------------------------------------------------
.end
-_gdrvno.s
* スタックフレーム状況
.offset 0
.ds.l 1 *リターンアドレス
_DRVNAMP: .ds.l 1 *引数: drvnamp
.text
.even
*---------------------------------------------------------------
*int get_drive_no(const char *drvnamp)
* ドライブ名からドライブ番号を得る
* 引数: drvnamp -ドライブ名("A:", "X:")
* (NULLまたは空文字列の場合はカレントドライブを取得する)
* 返値: ドライブ番号(=0:引数異常/=1-26:A-Z)
*---------------------------------------------------------------
.xdef _get_drive_no
_get_drive_no:
move.l _DRVNAMP(sp),d0 *drvnamp が
beq.s gdn_cur *NULL か
move.l d0,a0 *
tst.b (a0) *空文字列だったら
bne.s gdn_moji *
gdn_cur: * カレントドライブを得る
DOS __CURDRV *A=0,B=1,...
addq.l #1,d0 *0~25→1~26
jbra gdn0
gdn_moji: * ドライブ名から算出
moveq.l #0,d0
move.b (a0)+,d0
cmpi.b #'A',d0 *英大文字の範囲を
blo.s gdn_err *下回ってたら文句なくエラー
cmpi.b #'Z',d0 *範囲内
bhi.s @f *だったら
addi.b #'a'-'A',d0 *小文字にする
@@: subi.b #'a'-1,d0 *英小文字→数値変換
tst.b d0 *1~
ble.s gdn_err *26 の範囲に
cmpi.b #26,d0 *収まっていて
bgt.s gdn_err *
cmpi.b #':',(a0) *且つ2文字目が ':' なら
bne.s gdn_err *正しいドライブ名なのでその値を返す
gdn0:
rts
gdn_err: * ドライブ名がおかしい
moveq.l #0,d0
rts
*---------------------------------------------------------------
.end
-_ishunam.s
* スタックフレーム状況
LOCALSIZE equ -92
.offset LOCALSIZE
_NAMECKBUF: .ds.b 92 *__NAMECK バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
.text
.even
*---------------------------------------------------------------
*int is_human_name(const char *fnamp)
* ファイル名として正しいか判定する
* 引数: fnamp - 被検査ファイル名文字列アドレス
* 返値 正しければ !0、異常なら 0
*---------------------------------------------------------------
.xdef _is_human_name
_is_human_name:
link a6,#LOCALSIZE
pea.l _NAMECKBUF(a6)
move.l _FNAMP(a6),-(sp)
DOS __NAMECK
tst.l d0
sge.b d1
moveq.l #0,d0 *d0.l= 0:異常
move.b d1,d0 * ff:正常
unlk a6
rts
*---------------------------------------------------------------
.end
-_fexist.s
* スタックフレーム状況
LOCALSIZE equ -54
.offset LOCALSIZE
_FILESBUF: .ds.b 54 *__FILES バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_FNAMP: .ds.l 1 *引数: fnamp
_ATR: .ds.l 1 *引数: atr
.text
.even
*---------------------------------------------------------------
*int fexist(const char *fnamp, int atr)
* ファイルを探す
* 引数: fnamp - 探索ファイル名
* atr - 探索ファイルの属性
* 返値: あれば !0、なければ 0
*---------------------------------------------------------------
.xdef _fexist
_fexist:
link a6,#LOCALSIZE
move.w _ATR+2(a6),-(sp)
move.l _FNAMP(a6),-(sp)
pea.l _FILESBUF(a6)
DOS __FILES
tst.l d0
sge.b d1
moveq.l #0,d0
move.b d1,d0 * d0.l=ff(!0):ある/=0:ない
unlk a6
rts
*---------------------------------------------------------------
.end
-_gprognm.s
* 定数定義
NCK_NAME equ 67 *__NAMECK バッファ:ファイル主名の位置
* スタックフレーム状況
LOCALSIZE equ -92
.offset LOCALSIZE
_NAMECKBUF: .ds.b 92 *__NAMECK バッファ
.ds.l 1 *フレームポインタ
.ds.l 1 *リターンアドレス
_BUFP: .ds.l 1 *引数: bufp
_PNAMP: .ds.l 1 *引数: pnamp
.text
.even
*---------------------------------------------------------------
*void get_prog_name(char *bufp, const char *pnamp)
* プログラムタイトル抜き出し
* 引数: bufp - プログラムタイトル格納バッファアドレス
* pnamp - プログラム名へのポインタ(起動時の argv[0])
*---------------------------------------------------------------
.xdef _get_prog_name
_get_prog_name:
link a6,#LOCALSIZE
* プログラム名を構成要素に分解
lea.l _NAMECKBUF(a6),a0
pea.l (a0)
move.l _PNAMP(a6),-(sp)
DOS __NAMECK
;;; ADDQA 12,sp
* プログラム名の「ファイル主名」をバッファに転送
ADDQA NCK_NAME,a0
move.l _BUFP(a6),a1
@@: move.b (a0)+,(a1)+
bne.s @b
gpn0:
unlk a6
rts
*---------------------------------------------------------------
.end
-
- ここからしばらくCソース
-
-- Common Header
#define __DOS_INLINE__
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <jctype.h>
#include <jstring.h>
#include <sys\dos.h>
#include "easymac.h"
#include "dummyc.h"
#include "hufilec.h"
/* データ構造定義 */
typedef struct _filbuf _filesbuf_t; /* DOS __FILES ファイル情報 */
typedef struct _nameckbuf _nameckbuf_t; /* DOS __NAMECK ファイル名解析情報 */
/* 大安易マクロ */
#define is_path_sepa_mac(ch) (((ch) == '\\') || ((ch) == ':') || ((ch) == '/'))
/*
* ↓↓↓ ライブラリ共通関数 ↓↓↓
* inline 展開されることを期待する
*/
/* 自家製 strcpy()
* 引数: dstp - コピー先アドレス
* srcp - コピー元アドレス
*/
static
void ___vstrcpy(char *dstp, const char *srcp)
{
while (*dstp++ = *srcp++) {
}
}
-_fcatxup.c
/* ファイル名に拡張子を付加する
* 元から拡張子があれば何もしない
* ファイル名に英半角大文字が使われていれば拡張子を大文字変換し、
* 一文字も使われていなければ小文字変換して付加する
* ex) ファイル名:"Foo" 拡張子:"Bar" → "Foo.BAR"
* ファイル名:"foo" 拡張子:"Bar" → "foo.bar"
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
*/
char *fcatext_upper(char *fnamp, const char *extp)
{
char *xp;
xp = getextpos0(fnamp); /* 拡張子の位置取得 */
if (*xp == '\0') { /* 拡張子がなければ付加する */
_nameckbuf_t nbuf;
/* 拡張子付加 */
if (*extp != '.') { /* extp に '.' がなければ */
*xp++ = '.'; /* 先に書き込んでおく */
}
___vstrcpy(xp, extp);
/* 拡張子の大小変更 */
_dos_nameck(fnamp, &nbuf); /* ファイル名を分解 */
if (jstrchr_upper(nbuf.name)) { /* ファイル名に大文字があれば */
jstrupr(xp); /* 全て大文字 */
} else { /* ファイル名が全て小文字なら */
jstrlwr(xp); /* 全て小文字 */
}
}
return fnamp;
}
-_fcatxlo.c
/* ファイル名に拡張子を付加する
* 元から拡張子があれば何もしない
* ファイル名に英半角小文字が使われていれば拡張子を小文字変換し、
* 一文字も使われていなければ大文字変換して付加する
* ex) ファイル名:"Foo" 拡張子:"Bar" → "Foo.bar"
* ファイル名:"FOO" 拡張子:"Bar" → "FOO.BAR"
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
*/
char *fcatext_lower(char *fnamp, const char *extp)
{
char *xp;
xp = getextpos0(fnamp); /* 拡張子の位置取得 */
if (*xp == '\0') { /* 拡張子がなければ付加する */
_nameckbuf_t nbuf;
/* 拡張子付加 */
if (*extp != '.') { /* extp に '.' がなければ */
*xp++ = '.'; /* 先に書き込んでおく */
}
___vstrcpy(xp, extp);
/* 拡張子の大小変更 */
_dos_nameck(fnamp, &nbuf); /* ファイル名を分解 */
if (jstrchr_lower(nbuf.name)) { /* ファイル名に小文字があれば */
jstrlwr(xp); /* 全て小文字 */
} else { /* ファイル名が全て大文字なら */
jstrupr(xp); /* 全て大文字 */
}
}
return fnamp;
}
-_fchgxup.c
/* ファイル名の拡張子を付け替える
* 拡張子がなければ付加する
* ファイル名に英半角大文字が使われていれば拡張子を大文字変換し、
* 一文字も使われていなければ小文字変換して付け替える
* ex) ファイル名:"Foo.Baz" 拡張子:"Bar" → "Foo.BAR"
* ファイル名:"foo.Baz" 拡張子:"Bar" → "foo.bar"
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
*/
char *fchgext_upper(char *fnamp, const char *extp)
{
char *xp;
_nameckbuf_t nbuf;
/* 拡張子位置を探索 */
xp = getextpos0(fnamp);
if (*extp != '.') { /* extp に '.' がなければ */
*xp++ = '.'; /* 先に書き込んでおく */
}
___vstrcpy(xp, extp); /* そこに書き込む */
/* 拡張子の大小変更 */
_dos_nameck(fnamp, &nbuf); /* ファイル名を分解 */
if (jstrchr_upper(nbuf.name)) { /* ファイル名に大文字があれば */
jstrupr(xp); /* 全て大文字 */
} else { /* ファイル名が全て小文字なら */
jstrlwr(xp); /* 全て小文字 */
}
return fnamp;
}
-_fchgxlo.c
/* ファイル名の拡張子を付け替える
* 拡張子がなければ付加する
* ファイル名に英半角小文字が使われていれば拡張子を小文字変換し、
* 一文字も使われていなければ大文字変換して付け替える
* ex) ファイル名:"Foo.Baz" 拡張子:"Bar" → "Foo.bar"
* ファイル名:"FOO.Baz" 拡張子:"Bar" → "FOO.BAR"
*
* 引数: fnamp - ファイル名文字列アドレス
* extp - 拡張子文字列アドレス
* 返値: fnamp の値
*/
char *fchgext_lower(char *fnamp, const char *extp)
{
char *xp;
_nameckbuf_t nbuf;
/* 拡張子位置を探索 */
xp = getextpos0(fnamp);
if (*extp != '.') { /* extp に '.' がなければ */
*xp++ = '.'; /* 先に書き込んでおく */
}
___vstrcpy(xp, extp); /* そこに書き込む */
/* 拡張子の大小変更 */
_dos_nameck(fnamp, &nbuf); /* ファイル名を分解 */
if (jstrchr_lower(nbuf.name)) { /* ファイル名に小文字があれば */
jstrlwr(xp); /* 全て小文字 */
} else { /* ファイル名が全て大文字なら */
jstrupr(xp); /* 全て大文字 */
}
return fnamp;
}
-_rdfall.c
/* 指定ファイルを全て読み込む
* 引数: fnamp - ファイル名文字列へのポインタ
* fsizp - ファイルサイズ格納変数へのポインタ(=NULL:書き込まない)
* 返値: 読み込めればその読み込んだメモリのアドレス
* 読み込みに失敗した場合は NULL
* (*fsizp - ファイルサイズ)
* 注記 * 読み込んだメモリは malloc() によって確保された
* ものである。このため、その内容が不要になった時点で
* メモリ解放をしなくてはならない。
* * この関数が失敗するのは次の場合である。:
* ・ファイルが存在しない
* ・メモリが確保できない
* ・ファイルの読み込みに失敗
* このうち、最初の「ファイルが存在しない」時は (*fsizp) に
* 0 が格納される。また、他の理由で失敗した時は (*fsizp) に
* ファイルサイズが格納される。
* * 読み込みはバイナリで行なわれる。テキストデータを扱う
* 場合は注意すること。
*/
void *read_file_all(const char *fnamp, unsigned long *fsizp)
{
void *result = NULL;
unsigned long fsiz = 0;
FILE *fp;
_filesbuf_t fbuf;
if (_dos_files(&fbuf, fnamp, 0x2f) >= 0) { /* どうやらファイルはあるらしい */
fsiz = fbuf.filelen; /* ファイルサイズ取得 */
result = malloc(fsiz); /* そのぶんだけメモリ確保 */
if (result != NULL) { /* 確保できれば */
char errf = !0;
/* ファイルから読み込む */
fp = fopen(fnamp, "rb"); /* まず開く */
if (fp != NULL) { /* 開けていれば読む */
if (fread(result, 1, fsiz, fp) == fsiz) { /* 読み込めた */
errf = 0; /* 読み込み失敗フラグクリア */
}
fclose(fp);
}
if (errf) {
free_mem(result);
}
}
}
/* 返値設定 */
if (fsizp != NULL) { /* ファイルサイズが必要なら */
*fsizp = fsiz; /* 書き込んでおく */
}
return result;
}
-_mfpath.c
/* ファイル名をフルパス展開、再構成する
* 引数: fullp - フルパス再構成先バッファアドレス
* fnamp - 展開したいファイル名文字列
* 返値: 正常終了時は 0
* 展開/構成に失敗したら <0 (Humanエラーコード)
* 注記 * fnamp と fullp の指す領域が重なっていても構わない。
* * この関数ではファイルが実際にあるかどうかは確認しない。
*/
int make_full_path(char *fullp, const char *fnamp)
{
int result;
_nameckbuf_t nbuf;
result = _dos_nameck(fnamp, &nbuf);
if (result != 0) {
sprintf(fullp, "%c%c%s%s%s", nbuf.drive[0], nbuf.drive[1],
nbuf.path, nbuf.name, nbuf.ext);
result = 0;
}
return result;
}
-- Common Header.
/*
* ここから下はDOSコールを使わない関数を入れておく
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <jctype.h>
#include <jstring.h>
#include "easymac.h"
#include "dummyc.h"
#include "hufilec.h"
/* データ構造定義 */
typedef struct _filbuf _filesbuf_t; /* DOS __FILES ファイル情報 */
typedef struct _nameckbuf _nameckbuf_t; /* DOS __NAMECK ファイル名解析情報 */
/* 大安易マクロ */
#define is_path_sepa_mac(ch) (((ch) == '\\') || ((ch) == ':') || ((ch) == '/'))
/*
* ↓↓↓ ライブラリ共通関数 ↓↓↓
* inline 展開されることを期待する
*/
/* 自家製 strcpy()
* 引数: dstp - コピー先アドレス
* srcp - コピー元アドレス
*/
static
void ___vstrcpy(char *dstp, const char *srcp)
{
while (*dstp++ = *srcp++) {
}
}
/* 自家製 stpcpy()
* 引数: dstp - コピー先アドレス
* srcp - コピー元アドレス
* 返値: dstp 上のコピー終了時の'\0'のアドレス
*/
static
char *___stpcpy(char *dstp, const char *srcp)
{
while (*dstp++ = *srcp++) {
}
return (dstp - 1); /* 1文字行き過ぎてるので */
}
/* 自家製 strlast()
* 引数: strp - 被処理文字列アドレス
* 返値: strp の最後の'\0'の位置
*/
static
char *___strlast(const char *strp)
{
while (*strp++) {
}
return (char *)(strp - 1); /* 1文字行き過ぎてるので */
}
/*
* ↓↓↓ hufilec のみのライブラリ共通関数 ↓↓↓
* inline 展開されることを期待する
*/
/* 一番最後にあるパス区切り文字を探す
* 引数: fnamp - 被検索ファイル名へのポインタ
* 返値: 最後のパス区切り文字のアドレス
* 見つからなかったら NULL
*/
static
char *___find_last_sepa(const char *fnamp)
{
const char *cp = fnamp;
while (1) {
cp = strrpbrk(cp, "/:\\");
if ((cp == NULL) /* 見つからなかった */
|| (cp == fnamp) /* ファイル名の最初 */
|| !iskanji(*(cp - 1)) /* 漢字2バイト目でない */
) {
/* 区切り文字発見or見つからなかった */
break; /* これ以上回ってもしょうがないのでループ中断 */
}
}
return (char *)cp;
}
-_fgtnamp.c
/* フルパスファイル名文字列中のファイル名部分の開始アドレスを取得する
* 引数: fnamp - ファイル名へのポインタ
* 返値: fnamp 中のファイル名の開始アドレス
* 注記 * fnamp がファイル名だけだった場合は、fnamp をそのまま返す。
*/
char *fgetnamep(const char *fnamp)
{
char *result;
/* パス名の最後の位置を取得 */
result = ___find_last_sepa(fnamp);
if (result != NULL) { /* 見つかってたら */
result++; /* その次からがファイル名 */
} else { /* 見つからなければ */
result = (char *)fnamp; /* 文字列全てがファイル名 */
}
return result;
}
-_fcutpath.c
/* ファイル名からパス名(ドライブ名およびディレクトリ名)部分のみを切り出す
* 引数: pbufp - 切り出したパス名の格納バッファアドレス
* fnamp - 処理対象ファイル名へのポインタ
* 返値: pbufp の値
* 注記 * fnamp にパス名が存在しない場合、pbufp には空文字列が
* 格納される。
* * この関数は構成要素を字面から分解するだけであり、分解した
* 文字列が正しいかはチェックしない。
* * 漢字もそれなりに考慮しているが、完璧とは言えない。
*/
char *fcutpath(char *pbufp, const char *fnamp)
{
const char *endp;
/* パス名の最後の位置を保持しておく */
endp = ___find_last_sepa(fnamp);
/* パス名の切り出し */
while (fnamp <= endp) { /* パス名がない(endp == NULL)場合はここで引っ掛かるので転送されない */
*pbufp++ = *fnamp++;
}
*pbufp = '\0';
return pbufp;
}
-_sepfnam.c
/* ファイル名を各構成要素に分解する
* 引数: drvp - ドライブ名("O:" など)格納バッファアドレス
* dirp - ディレクトリ名("Here\comes\" など)格納バッファアドレス
* basep - ファイル名("The_Newest" など)格納バッファアドレス
* extp - 拡張子(".Day" など)格納バッファアドレス
* fnamp - 分解されるファイル名へのポインタ
* 注記 * 該当する要素が fnamp に存在しない場合、バッファには
* 空文字列が格納される。
* * 渡されたバッファアドレスが NULL だったら、その構成要素は
* バッファに書き込まない。
* * この関数は構成要素を字面から分解するだけであり、分解した
* 文字列が正しいかはチェックしない。
* * 漢字もそれなりに考慮しているが、完璧とは言えない。
*/
void separate_file_name(char *drvp, char *dirp, char *basep, char *extp, const char *fnamp)
{
char drvexist = (fnamp[1] == ':');
const char *stap, *endp;
/* パス名の最後の位置を保持しておく */
endp = ___find_last_sepa(fnamp);
/* ドライブ名 */
if (drvp != NULL) {
if (drvexist) { /* ドライブ名があれば分解 */
*drvp++ = fnamp[0];
*drvp++ = fnamp[1];
}
*drvp = '\0';
}
/* ディレクトリ名 */
if (dirp != NULL) {
stap = (drvexist)? &fnamp[2]: fnamp;
while (stap <= endp) { /* パス名がない(endp == NULL)場合はここで引っ掛かるので転送されない */
*dirp++ = *stap++;
}
*dirp = '\0';
}
/* ファイル名 */
if (basep != NULL) {
stap = (endp == NULL)? fnamp: endp + 1;
strcpy_brk(basep, stap, "."); /* 拡張子があればそこまで、なければ最後まで */
}
/* 拡張子 */
if (extp != NULL) {
stap = getextpos0(fnamp); /* stap=拡張子開始位置 */
while (*extp++ = *stap++) { /* 終わりまでコピー */
}
}
}
-_rmkfnam.c
#define ATR 0x3f
/* ファイル名の拡張子をすげ替えて、存在しないファイル名を作成する
* 引数: fnbufp - ファイル名の基準文字列
* & 作成ファイル名の格納バッファアドレス
* 返値: 作成できれば fnbufp、できなければ NULL
* 注記 * 拡張子変更前のファイル名が存在するかはチェックしない。
* * fnbufp には、3文字の拡張子が格納できるだけの容量が必要
* である。
* * ファイル名の変更は、拡張子を"000"~"999"に書き換えること
* で行なう。そのどれもが存在していたら「作成できない」ことに
* なる。
* * 作成できなければ、fnbufp は同じ文字列になる。
*/
char *remake_unsame_filename(char *fnbufp)
{
short i;
char *xp; /* 拡張子開始位置 */
char xkeep[8]; /* 拡張子保存域 */
#if 0
/* 変更前のがあるのか調べてみる */
if (!fexist(fnbufp, ATR)) { /* なければ */
return fnbufp; /* そのままでいい */
}
#endif
/* 元の拡張子を保存 */
xp = getextpos0(fnbufp); /* xp=拡張子の位置 */
___vstrcpy(xkeep, xp); /* 今の拡張子を保存しておく */
/* 拡張子変更・存在判定ループ
* ※このキミョーなループ処理は、dbra を使わせるための処置。
*/
i = 1000 - 1;
do {
sprintf(xp, ".%.3d", (1000 - 1) - i); /* 拡張子書き込み */
if (!fexist(fnbufp, ATR)) { /* そのファイルがなければ */
return fnbufp; /* それを持って返る */
}
} while (--i != -1);
/* 全て存在していた */
___vstrcpy(xp, xkeep); /* 保存していた拡張子を書き戻す */
return NULL;
}
-_fcatpat.c
/* ファイル名冒頭にパス名を付加する
* パスが指定されていたら付加しない
*
* 引数: fnamp - ファイル名文字列へのポインタ
* 兼 処理結果格納バッファアドレス
* pathp - パス名文字列へのポインタ
* 返値: fnamp の値
* 注記 * pathp が空文字列だった場合、パス名の付加は行なわれ
* ない。
* * pathp の最後に '\'(バックスラッシュ)または '/'(スラッシュ) が
* なかったら、「環境変数 SLASH が定義されていれば '/'、
* 未定義ならば '\'」を付加する。
* * fnamp にはパス名を付加できるだけの余裕が必要である。
*/
char *fcatpath(char *fnamp, const char *pathp)
{
char *cp, *kp;
if (!is_null_str(pathp)) { /* pathp が空でなければ */
if (!is_there_path(fnamp)) { /* パス名が指定されてない */
kp = strdup(fnamp); /* まずファイル名を保存 */
cp = ___stpcpy(fnamp, pathp); /* パス名をバッファ冒頭にコピー */
if (!is_path_sepa_mac(*(cp - 1))) { /* 最後に区切りがなければ */
*cp++ = path_separator(); /* 付加しておいてから */
}
___vstrcpy(cp, kp); /* その後ろに保存しといたファイル名を転送 */
}
}
return fnamp; /* 引数のアドレスをそのまま返す */
}
-_fgsssp.c
/* テキストファイルから1行読み込む
* 読み込んだ行の先頭に空白文字があればそれを読み飛ばす
*
* 引数: bufp - 格納バッファアドレス
* size - 読み込むサイズ
* fp - 読み込みファイルポインタ
* 返値: エラー又は EOF の場合は NULL、
* でなければ読み込み行の行頭にある空白文字を
* スキップしたアドレス
*/
char *fgets_skipsp(char *bufp, size_t size, FILE *fp)
{
char *result;
result = fgets(bufp, size, fp);
if (result != NULL) {
while (isspace(*result)) {
result++;
}
}
return result;
}
-_fgetsb.c
/* fgets バイナリ版
* バイナリオープンされたファイルから fgets() した
* 文字列の最後から2文字目が '\r' だった場合にそれを削除、
* 以降の文字を1つ前にずらす
*
* 引数: bufp - 読み込み内容格納バッファアドレス
* size - 最大読み込みサイズ
* fp - 読み込みファイルのファイルポインタ
* 返値: 成功すれば bufp、失敗したか EOF だったら NULL
* 注記 * 最後から2文字目以外の '\r' 文字には手を付けない。
*/
char *fgetsb(char *bufp, size_t size, FILE *fp)
{
bufp = fgets(bufp, size, fp);
if (bufp != NULL) { /* 読み込めてたら */
/* 行末チェック */
char *cp = ___strlast(bufp) - 2; /* cp='\r' がありそうな場所 */
if ((cp >= bufp) && (*cp == '\r')) { /* 実際に '\r' があれば */
*cp = *(cp + 1); /* その後ろの1文字で '\r' を上書き */
*(cp + 1) = '\0'; /* 文字列を終わらせる */
}
}
return bufp;
}
-_fgetsnn.c
/* ファイルから一行読み込む
* 行末にある改行 '\n' または復帰改行 '\r\n' は取り除かれる
*
* 引数: bufp - 読み込み行の格納バッファアドレス
* size - 格納バッファのサイズ
* fp - 読み込みファイルポインタ
* 返値: 成功すれば bufp、失敗したか EOF だったら NULL
*/
char *fgetsnn(char *bufp, size_t size, FILE *fp)
{
bufp = fgets(bufp, size, fp);
if (bufp != NULL) { /* 読み込めてたら */
/* 行末チェック */
char *cp = ___strlast(bufp) - 1; /* cp='\r\n' がありそうな場所 */
if (*cp == '\n') { /* 改行文字発見 */
if (*(cp - 1) == '\r') { /* その前に復帰文字もある */
--cp;
}
*cp = '\0'; /* 文字列を完結させる */
}
}
return bufp;
}
-_setstim.c
#include <utime.h>
#include <sys\stat.h>
/* ファイル日時をもう一つのファイルに合わせる
* 引数: dstfnp - 日時変更するファイル名
* srcfnp - 変更日時元のファイル名
* 返値: 設定できれば 0、エラーがあったら !0
*/
int set_same_file_time(const char *dstfnp, const char *srcfnp)
{
int result = !0;
struct stat stbuf;
if (stat(srcfnp, &stbuf) == 0) {
if (utime(dstfnp, (struct utimbuf *)&(stbuf.st_atime)) == 0) {
result = 0;
}
}
return result;
}
-_setftim.c
#include <time.h>
#include <utime.h>
/* ファイル日時を設定する
* 引数: fnamp - 日時変更するファイル名
* tim - 設定日時
* (世界標準時(UTC)での1970年1月1日午前0時0分0秒からの通算秒数)
* 返値: 設定できれば 0、エラーがあったら !0
*/
int set_file_time(const char *fnamp, time_t tim)
{
struct utimbuf utbuf;
utbuf.modtime = tim;
return utime(fnamp, &utbuf);
}
-_getftim.c
#include <time.h>
#include <sys\stat.h>
/* ファイル日時を取得する
* 引数: fnamp - 日時変更するファイル名
* 返値: 指定ファイルの最終更新日時
* (世界標準時(UTC)での1970年1月1日午前0時0分0秒からの通算秒数)
* エラーがあったら -1
*/
time_t get_file_time(const char *fnamp)
{
time_t result = 0;
struct stat sts;
if (!stat(fnamp, &sts)) {
result = sts.st_mtime;
}
return result;
}